package com.gitee.kamismile.stone.basic.data.domain.sysRes.service.impl;

import com.gitee.kamismile.stone.basic.data.domain.sysRes.repository.entity.SysResources;
import com.gitee.kamismile.stone.basic.data.domain.sysRes.service.ISysResDomainService;
import com.gitee.kamismile.stone.basic.data.infrastructure.enums.ResErrorEnum;
import com.gitee.kamismile.stone.basic.data.infrastructure.repository.r2Repository.sysRes.repository.SysResRepository;
import com.gitee.kamismile.stone.basic.data.infrastructure.utils.CriteriaQueryBuilder;
import com.gitee.kamismile.stone.basic.data.infrastructure.utils.PageQueryBuilder;
import com.gitee.kamismile.stone.basic.data.infrastructure.utils.QueryBuilder;
import com.gitee.kamismile.stone.commmon.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

@Service
public class SysResDomainServiceImpl implements ISysResDomainService {
    @Autowired
    private R2dbcEntityTemplate template;

    @Autowired
    private SysResRepository sysResRepository;
    @Override
    public Mono<SysResources> saveOrUpdate(SysResources sysResources) {
        return sysResRepository.save(sysResources);
    }

    @Override
    public Mono<Void> deleteSysResById(Integer nResourcesId) {
        return sysResRepository.deleteById(nResourcesId);
    }

    @Override
    public Mono<Page<SysResources>> findResPage(int page, int size, Criteria criteria) {
       Pageable pageable = PageRequest.of(page, size);
        return new PageQueryBuilder<>(template, SysResources.class)
                .where(criteria)
                .pageable(pageable)
                .apply();
    }

    @Override
    public Mono<SysResources> findAndCheckResById(Integer nResourcesId, Integer nTenantId) {
        return findResById(nResourcesId, nTenantId)
                .switchIfEmpty(Mono.defer(() -> Mono.error(
                        new BusinessException(
                                ResErrorEnum.ResNotFound.getCode(),
                                ResErrorEnum.ResNotFound.getMessage()
                        ))));
    }

    public Mono<SysResources> findResById(Integer nResourcesId, Integer nTenantId) {
        Assert.notNull(nResourcesId, ResErrorEnum.ResNotNull.getMessage());
        SysResources example = new SysResources();
        example.setnResourcesId(nResourcesId);
        example.setnTenantId(nTenantId);
        return sysResRepository.findOne(Example.of(example));
    }


    public Flux<SysResources> findResByIds(List<Integer> nResourcesIds, String sType, String sParentType, Integer nParentId){
        Criteria criteria = CriteriaQueryBuilder.builder()
                .inIgnoreEmpty("nResourcesId", nResourcesIds)
                .eqIgnoreEmpty("sType",sType)
                .eqIgnoreEmpty("sParentType",sParentType)
                .eqIgnoreEmpty("nParentId",nParentId)
                 .create();
            return new QueryBuilder<>(template, SysResources.class)
                .where(criteria)
                .apply().all();
    }

    @Override
    public Flux<SysResources> findResByIds(List<Integer> nResourcesIds) {
        return findResByIds(nResourcesIds,null,null,null);
    }
}
